<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Bar Chart</title>
    <link rel="stylesheet" type="text/css" href="../../css/styles.css"/>
    <script type="text/javascript" src="../../lib/d3.js"></script>
</head>

<body>

<script type="text/javascript">
function barChart() {
    var _chart = {};

    var _width = 600, _height = 250,
            _margins = {top: 30, left: 30, right: 30, bottom: 30},
            _x, _y,
            _data = [],
            _colors = d3.scaleOrdinal(d3.schemeCategory10),
            _svg,
            _bodyG;

    _chart.render = function () {
        if (!_svg) {
            _svg = d3.select("body").append("svg")
                    .attr("height", _height)
                    .attr("width", _width);

            renderAxes(_svg);

            defineBodyClip(_svg);
        }

        renderBody(_svg);
    };

    function renderAxes(svg) {
        var axesG = svg.append("g")
                .attr("class", "axes");

        var xAxis = d3.axisBottom()
                .scale(_x.range([0, quadrantWidth()]));

        var yAxis = d3.axisLeft()
                .scale(_y.range([quadrantHeight(), 0]));

        axesG.append("g")
                .attr("class", "axis")
                .attr("transform", function () {
                    return "translate(" + xStart() + "," + yStart() + ")";
                })
                .call(xAxis);

        axesG.append("g")
                .attr("class", "axis")
                .attr("transform", function () {
                    return "translate(" + xStart() + "," + yEnd() + ")";
                })
                .call(yAxis);
    }

    function defineBodyClip(svg) {
        var padding = 5;

        svg.append("defs")
                .append("clipPath")
                .attr("id", "body-clip")
                .append("rect")
                .attr("x", 0)
                .attr("y", 0)
                .attr("width", quadrantWidth() + 2 * padding)
                .attr("height", quadrantHeight());
    }

    function renderBody(svg) {
        if (!_bodyG)
            _bodyG = svg.append("g")
                    .attr("class", "body")
                    .attr("transform", "translate(" 
                            + xStart() 
                            + "," 
                            + yEnd() + ")")
                    .attr("clip-path", "url(#body-clip)");

        renderBars();
    }
    
    function renderBars() {
        var padding = 2; // <-A

        var bars = _bodyG.selectAll("rect.bar")
                .data(_data);
        bars.enter()
                .append("rect") // <-B
            .merge(bars)
                .attr("class", "bar")
            .transition()
                .attr("x", function (d) { 
                    return _x(d.x); // <-C
                })
                .attr("y", function (d) { 
                    return _y(d.y); // <-D 
                })
                .attr("height", function (d) { 
                    return yStart() - _y(d.y); 
                })
                .attr("width", function(d){
                    return Math.floor(quadrantWidth() / _data.length) - padding;
                });
    }

    function xStart() {
        return _margins.left;
    }

    function yStart() {
        return _height - _margins.bottom;
    }

    function xEnd() {
        return _width - _margins.right;
    }

    function yEnd() {
        return _margins.top;
    }

    function quadrantWidth() {
        return _width - _margins.left - _margins.right;
    }

    function quadrantHeight() {
        return _height - _margins.top - _margins.bottom;
    }

    _chart.width = function (w) {
        if (!arguments.length) return _width;
        _width = w;
        return _chart;
    };

    _chart.height = function (h) {
        if (!arguments.length) return _height;
        _height = h;
        return _chart;
    };

    _chart.margins = function (m) {
        if (!arguments.length) return _margins;
        _margins = m;
        return _chart;
    };

    _chart.colors = function (c) {
        if (!arguments.length) return _colors;
        _colors = c;
        return _chart;
    };

    _chart.x = function (x) {
        if (!arguments.length) return _x;
        _x = x;
        return _chart;
    };

    _chart.y = function (y) {
        if (!arguments.length) return _y;
        _y = y;
        return _chart;
    };

    _chart.setSeries = function (series) {
        _data = series;
        return _chart;
    };

    return _chart;
}

function randomData() {
    return Math.random() * 9;
}

function update() {
    data.length = 0;
    for (var j = 0; j < numberOfDataPoint; ++j)
        data.push({x: j, y: randomData()});    

    chart.render();
}

var numberOfDataPoint = 31,
    data = [];

data = d3.range(numberOfDataPoint).map(function (i) {
    return {x: i, y: randomData()};
});

var chart = barChart()
        .x(d3.scaleLinear().domain([-1, 32]))
        .y(d3.scaleLinear().domain([0, 10]));


chart.setSeries(data);

chart.render();
</script>

<div class="control-group">
    <button onclick="update()">Update</button>
</div>

</body>

</html>